#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
房间占用数据分割工具
将大的CSV文件按日期分割成多个小文件，便于前端快速加载
"""

import pandas as pd
import os
from datetime import datetime
import json

def analyze_data():
    """分析原始数据的基本信息"""
    print("=== 数据分析 ===")
    
    # 读取原始数据
    df = pd.read_csv('data/room_occupancy.csv')
    
    print(f"总记录数: {len(df):,}")
    print(f"日期范围: {df['Date'].min()} 到 {df['Date'].max()}")
    print(f"唯一日期数: {df['Date'].nunique()}")
    
    # 统计每日记录数
    daily_counts = df['Date'].value_counts().sort_index()
    print(f"平均每日记录数: {daily_counts.mean():.1f}")
    print(f"最多记录的日期: {daily_counts.max()}")
    print(f"最少记录的日期: {daily_counts.min()}")
    
    return df, daily_counts

def convert_date_format(date_str):
    """转换日期格式从 DD-MM-YYYY 到 YYYY-MM-DD"""
    parts = date_str.split('-')
    if len(parts) == 3:
        day, month, year = parts
        # 处理两位数年份，转换为四位数
        if len(year) == 4:
            # 已经是四位数年份
            full_year = year
        else:
            # 两位数年份，需要补充世纪
            full_year = f"20{year}"
        return f"{full_year}-{month.zfill(2)}-{day.zfill(2)}"
    return date_str

def create_directory_structure():
    """创建目录结构"""
    base_dir = "Data_visul"
    
    # 创建主目录
    if not os.path.exists(base_dir):
        os.makedirs(base_dir)
        print(f"创建目录: {base_dir}")
    
    # 创建子目录
    subdirs = [
        "daily",      # 按日期分割的文件
        "weekly",     # 按周分割的文件  
        "monthly",    # 按月分割的文件
        "hourly",     # 按小时分割的文件
        "metadata"    # 元数据文件
    ]
    
    for subdir in subdirs:
        full_path = os.path.join(base_dir, subdir)
        if not os.path.exists(full_path):
            os.makedirs(full_path)
            print(f"创建目录: {full_path}")
    
    return base_dir

def split_by_date(df, base_dir):
    """按日期分割数据"""
    print("=== 按日期分割数据 ===")
    try:
        # 直接使用pandas的日期解析，指定格式
        df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], format='%d-%m-%Y %H:%M:%S')
        df['DateOnly'] = df['DateTime'].dt.date
        
        # 按日期分组
        grouped = df.groupby('DateOnly')
        
        daily_dir = os.path.join(base_dir, 'daily')
        file_info = []
        
        for date, group in grouped:
            filename = f"room_data_{date.strftime('%Y%m%d')}.csv"
            filepath = os.path.join(daily_dir, filename)
            
            # 保存原始格式的数据（不包含我们添加的DateTime列）
            original_columns = [col for col in group.columns if col not in ['DateTime', 'DateOnly']]
            group[original_columns].to_csv(filepath, index=False)
            
            file_info.append({
                'date': date.strftime('%Y-%m-%d'),
                'filename': filename,
                'records': len(group),
                'file_size_kb': round(os.path.getsize(filepath) / 1024, 2)
            })
            print(f"保存日期 {date}: {len(group)} 条记录 -> {filename}")
        
        return file_info
    except Exception as e:
        print(f"错误: {e}")
        import traceback
        traceback.print_exc()
        return []

def split_by_hour(df, base_dir):
    """按小时分割数据（用于高精度分析）"""
    print("\n=== 按小时分割数据 ===")
    
    hourly_dir = os.path.join(base_dir, "hourly")
    file_info = []
    
    # 添加小时列
    df['Hour'] = df['DateTime'].dt.hour
    df['DateHour'] = df['DateTime'].dt.strftime('%Y-%m-%d_%H')
    
    for date_hour in df['DateHour'].unique():
        hourly_data = df[df['DateHour'] == date_hour].copy()
        
        # 按时间排序
        hourly_data = hourly_data.sort_values('DateTime')
        
        # 生成文件名
        filename = f"room_data_{date_hour}h.csv"
        filepath = os.path.join(hourly_dir, filename)
        
        # 保存文件
        hourly_data.to_csv(filepath, index=False)
        
        # 记录文件信息
        file_info.append({
            'filename': filename,
            'date_hour': date_hour,
            'records': len(hourly_data),
            'file_size_kb': round(os.path.getsize(filepath) / 1024, 2)
        })
        
        if len(hourly_data) > 0:  # 只打印有数据的小时
            print(f"创建文件: {filename} ({len(hourly_data)} 条记录)")
    
    return file_info

def split_by_week(df, base_dir):
    """按周分割数据"""
    print("\n=== 按周分割数据 ===")
    
    weekly_dir = os.path.join(base_dir, "weekly")
    file_info = []
    
    # 添加周信息
    df['Week'] = df['DateTime'].dt.isocalendar().week
    df['Year'] = df['DateTime'].dt.year
    df['YearWeek'] = df['Year'].astype(str) + '_W' + df['Week'].astype(str).str.zfill(2)
    
    for year_week in df['YearWeek'].unique():
        weekly_data = df[df['YearWeek'] == year_week].copy()
        
        # 按时间排序
        weekly_data = weekly_data.sort_values('DateTime')
        
        # 生成文件名
        filename = f"room_data_{year_week}.csv"
        filepath = os.path.join(weekly_dir, filename)
        
        # 保存文件
        weekly_data.to_csv(filepath, index=False)
        
        # 记录文件信息
        file_info.append({
            'filename': filename,
            'year_week': year_week,
            'records': len(weekly_data),
            'file_size_kb': round(os.path.getsize(filepath) / 1024, 2),
            'date_range': {
                'start': weekly_data['Date'].min(),
                'end': weekly_data['Date'].max()
            }
        })
        
        print(f"创建文件: {filename} ({len(weekly_data)} 条记录)")
    
    return file_info

def split_by_month(df, base_dir):
    """按月分割数据"""
    print("\n=== 按月分割数据 ===")
    
    monthly_dir = os.path.join(base_dir, "monthly")
    file_info = []
    
    try:
        # 直接使用pandas的日期解析
        df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], format='%d-%m-%Y %H:%M:%S')
        df['Month'] = df['DateTime'].dt.month
        df['Year'] = df['DateTime'].dt.year
        df['YearMonth'] = df['Year'].astype(str) + '_' + df['Month'].astype(str).str.zfill(2)
        
        # 按年月分组
        grouped = df.groupby(['Year', 'Month'])
        
        for (year, month), monthly_data in grouped:
            filename = f"room_data_{year}_{month:02d}月.csv"
            filepath = os.path.join(monthly_dir, filename)
            
            # 保存原始格式的数据
            original_columns = [col for col in monthly_data.columns if col not in ['DateTime', 'Month', 'Year', 'YearMonth']]
            monthly_data[original_columns].to_csv(filepath, index=False)
            
            # 记录文件信息
            file_info.append({
                'filename': filename,
                'year': int(year),  # 转换为Python int
                'month': int(month),  # 转换为Python int
                'month_name': f"{year}年{month}月",
                'records': len(monthly_data),
                'file_size_kb': round(os.path.getsize(filepath) / 1024, 2),
                'date_range': {
                    'start': monthly_data['Date'].min(),
                    'end': monthly_data['Date'].max()
                }
            })
            
            print(f"创建文件: {filename} ({len(monthly_data)} 条记录)")
        
        return file_info
    except Exception as e:
        print(f"错误: {e}")
        import traceback
        traceback.print_exc()
        return []

def create_metadata(df, daily_info, hourly_info, weekly_info, monthly_info, base_dir):
    """创建元数据文件"""
    print("\n=== 创建元数据 ===")
    
    metadata_dir = os.path.join(base_dir, "metadata")
    
    # 主要元数据
    main_metadata = {
        'created_at': datetime.now().isoformat(),
        'source_file': 'data/room_occupancy.csv',
        'total_records': len(df),
        'date_range': {
            'start': df['Date'].min(),
            'end': df['Date'].max()
        },
        'unique_dates': df['Date'].nunique(),
        'file_counts': {
            'daily': len(daily_info),
            'hourly': len(hourly_info),
            'weekly': len(weekly_info),
            'monthly': len(monthly_info)
        },
        'sensor_info': {
            'temperature_sensors': 4,
            'light_sensors': 4,
            'sound_sensors': 4,
            'co2_sensors': 1,
            'pir_sensors': 2
        },
        'data_columns': list(df.columns)
    }
    
    # 保存主元数据
    with open(os.path.join(metadata_dir, 'main_metadata.json'), 'w', encoding='utf-8') as f:
        json.dump(main_metadata, f, indent=2, ensure_ascii=False)
    
    # 保存每日文件信息
    with open(os.path.join(metadata_dir, 'daily_files.json'), 'w', encoding='utf-8') as f:
        json.dump(daily_info, f, indent=2, ensure_ascii=False)
    
    # 保存每小时文件信息
    with open(os.path.join(metadata_dir, 'hourly_files.json'), 'w', encoding='utf-8') as f:
        json.dump(hourly_info, f, indent=2, ensure_ascii=False)
    
    # 保存每周文件信息
    with open(os.path.join(metadata_dir, 'weekly_files.json'), 'w', encoding='utf-8') as f:
        json.dump(weekly_info, f, indent=2, ensure_ascii=False)
    
    # 保存每月文件信息
    with open(os.path.join(metadata_dir, 'monthly_files.json'), 'w', encoding='utf-8') as f:
        json.dump(monthly_info, f, indent=2, ensure_ascii=False)
    
    # 创建文件索引（便于前端快速查询）
    file_index = {
        'daily': {item['date']: item for item in daily_info},
        'weekly': {item['year_week']: item for item in weekly_info},
        'hourly': {item['date_hour']: item for item in hourly_info},
        'monthly': {f"{item['year']}_{item['month']:02d}": item for item in monthly_info}
    }
    
    with open(os.path.join(metadata_dir, 'file_index.json'), 'w', encoding='utf-8') as f:
        json.dump(file_index, f, indent=2, ensure_ascii=False)
    
    print("元数据文件创建完成")
    
    return main_metadata

def create_sample_files(df, base_dir):
    """创建示例文件（用于前端测试）"""
    print("\n=== 创建示例文件 ===")
    
    sample_dir = os.path.join(base_dir, "samples")
    if not os.path.exists(sample_dir):
        os.makedirs(sample_dir)
    
    # 创建小样本（100条记录）
    small_sample = df.head(100)
    small_sample.to_csv(os.path.join(sample_dir, 'sample_small_100.csv'), index=False)
    
    # 创建中等样本（500条记录）
    medium_sample = df.head(500)
    medium_sample.to_csv(os.path.join(sample_dir, 'sample_medium_500.csv'), index=False)
    
    # 创建一个完整日期的样本
    first_date = df['Date'].iloc[0]
    daily_sample = df[df['Date'] == first_date]
    # 将日期格式从DD-MM-YYYY转换为YYYYMMDD用于文件名
    date_for_filename = first_date.replace('-', '')
    daily_sample.to_csv(os.path.join(sample_dir, f'sample_daily_{date_for_filename}.csv'), index=False)
    
    print(f"示例文件创建完成: small(100), medium(500), daily({len(daily_sample)})")

def main():
    """主函数"""
    print("房间占用数据分割工具")
    print("=" * 50)
    
    try:
        # 分析数据
        df, daily_counts = analyze_data()
        
        # 创建目录结构
        base_dir = create_directory_structure()
        
        # 按不同方式分割数据
        daily_info = split_by_date(df, base_dir)
        hourly_info = split_by_hour(df, base_dir)
        weekly_info = split_by_week(df, base_dir)
        monthly_info = split_by_month(df, base_dir)
        
        # 创建元数据
        metadata = create_metadata(df, daily_info, hourly_info, weekly_info, monthly_info, base_dir)
        
        # 创建示例文件
        create_sample_files(df, base_dir)
        
        # 输出摘要
        print("\n" + "=" * 50)
        print("数据分割完成!")
        print(f"总共创建了 {len(daily_info) + len(hourly_info) + len(weekly_info) + len(monthly_info)} 个文件")
        print(f"按日期: {len(daily_info)} 个文件")
        print(f"按小时: {len(hourly_info)} 个文件") 
        print(f"按周: {len(weekly_info)} 个文件")
        print(f"按月份: {len(monthly_info)} 个文件")
        print(f"文件保存在: {os.path.abspath(base_dir)}")
        
        # 文件大小统计
        total_size = sum([item['file_size_kb'] for item in daily_info + hourly_info + weekly_info + monthly_info])
        print(f"总文件大小: {total_size:.2f} KB ({total_size/1024:.2f} MB)")
        
        print("\n建议的前端使用方式:")
        print("1. 日常浏览使用daily文件 (平均每个文件约 500 条记录)")
        print("2. 详细分析使用hourly文件 (精确到小时)")
        print("3. 趋势分析使用weekly文件 (按周汇总)")
        print("4. 月度统计使用monthly文件 (按月分组)")
        print("5. 快速测试使用samples目录下的示例文件")
        
    except Exception as e:
        print(f"错误: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main() 